﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;

namespace HRZoneTrainer
{
    public class ZoneCalculation
    {
        public ZoneCalculation(int hRThreshold, int hRMaximum, string currentZoneSelection)
        {
            CurrentZoneSelection = currentZoneSelection;
            HRThreshold = hRThreshold;
            HRMaximum = hRMaximum;

            LoadConfig();
        }

        public void LoadConfig()
        {
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(Zones));
                FileStream fs = new FileStream(m_filePath, FileMode.Open, FileAccess.Read);

                object cfgObj = xs.Deserialize(fs);

                if ( cfgObj is Zones )
                {
                    Zones = cfgObj as Zones;
                }

                fs.Close();
            }
            catch ( Exception exception )
            {
                MessageBox.Show(exception.Message);
            }
        }

        public int CurrentZoneSelectionIndex
        {
            get
            {
                int nIndex = 0;

                for ( int x = 0; x < Zones.Items.Length; x++ )
                {
                    if ( Zones.Items[x].Name == CurrentZoneSelection )
                    {
                        nIndex = x;
                        break;
                    }
                }

                return ( nIndex );
            }
        }

        public string CurrentZoneSelection { get; set; }
        public int HRThreshold { get; set; }
        public int HRMaximum { get; set; }
        public Zones Zones { get; set; }

        private string m_filePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar + "HR Zone Trainer" + Path.DirectorySeparatorChar + "Zones.xml";

        internal double CalculateLower(string zoneName)
        {
            ZonesZoneTrainingZonesTrainingZonePercentage percentage = GetZonesPercentage(zoneName);

            return ( GetHRPercentage(percentage.Lower) );
        }

        internal double CalculateUpper(string zoneName)
        {
            ZonesZoneTrainingZonesTrainingZonePercentage percentage = GetZonesPercentage(zoneName);
            return ( GetHRPercentage(percentage.Upper) );
        }

        private double GetHRPercentage(double percentage)
        {
            double HRPercentage = 0.0;

            if ( GetZoneCalculationMethod() == "Threshold" )
            {
                HRPercentage = (HRThreshold * percentage) / 100.0;
            }
            else if ( GetZoneCalculationMethod() == "Maximum" )
            {
                HRPercentage = ( HRMaximum * percentage ) / 100.0;
            }

            return ( HRPercentage );
        }

        public string GetZoneCalculationMethod()
        {
            return ( Zones.Items[CurrentZoneSelectionIndex].PercentageOf );
        }

        private ZonesZoneTrainingZonesTrainingZonePercentage GetZonesPercentage(string zoneName)
        {
            ZonesZoneTrainingZonesTrainingZonePercentage percentage = null;

            foreach ( ZonesZoneTrainingZonesTrainingZone thisZone in Zones.Items[CurrentZoneSelectionIndex].TrainingZones )
            {
                if ( thisZone.Name == zoneName )
                {
                    percentage = thisZone.Percentage;
                    break;
                }
            }

            return ( percentage );
        }

        public int GetLowerZoneHR(int intensity)
        {
            int zoneHRLower = 0;
            int HR = HRThreshold;

            if (GetZoneCalculationMethod() == "Maximum") {
                HR = HRMaximum;
            }

            foreach ( ZonesZoneTrainingZonesTrainingZone thisZone in Zones.Items[CurrentZoneSelectionIndex].TrainingZones )
            {
                if ( (intensity >= thisZone.Percentage.Lower) && (intensity < thisZone.Percentage.Upper) )
                {
                    zoneHRLower = (int) ((thisZone.Percentage.Lower * HR) / 100.0);
                }
            }

            return ( zoneHRLower );
        }

        public int GetUpperZoneHR(int intensity)
        {
            int zoneHRUpper = 0;
            int HR = HRThreshold;

            if ( GetZoneCalculationMethod() == "Maximum" )
            {
                HR = HRMaximum;
            }

            foreach ( ZonesZoneTrainingZonesTrainingZone thisZone in Zones.Items[CurrentZoneSelectionIndex].TrainingZones )
            {
                if ( ( intensity >= thisZone.Percentage.Lower ) && ( intensity < thisZone.Percentage.Upper ) )
                {
                    zoneHRUpper = (int) ( ( thisZone.Percentage.Upper * HR ) / 100.0 );
                }
            }

            return ( zoneHRUpper );
        }
    }
}
